/**
 * OWLtoGraph.java
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 * @author skrivov
 * Created on Oct 14, 2004
 *
 */
package abdn.graph.growl;
//Java utilities for the GUI
import java.net.*;
//Packages needed for the graph
import java.util.*;
import java.io.*;
import java.awt.*;
import javax.swing.*;
//Packages needed to deal with the Ontology
import org.semanticweb.owl.io.vocabulary.*;
import org.semanticweb.owl.model.*;
import org.semanticweb.owl.model.helper.*;

import abdn.graph.ontobrowser.*;
//Packages needed to work
import abdn.CleanONTO.*;
import abdn.CleanONTO.util.*;
//Packages needed for the graphic part of the software
import com.touchgraph.graphlayout.*;
import com.touchgraph.graphlayout.graphelements.*;

public class OWLtoGraph {
  public static final int OWLRDF = 0;
  public static final int Abstract = 1;
  EntityVector entities = null;
  TGPanel tgPanel;
  ESDOntoBrowser esdOntoBrowser;
  OWLOntology currentOntology = null;
  BuildGraphVisitor visitor = null;
  Set includeOntologies = null;
  OWLMetadata metadata;
  // keep track of which OWL model entities have been processed to avoid node
  // duplication when entities are included in multiple ontologies due to imports
  HashSet processedEntities = new HashSet();
  HashMap nodeEntities = new HashMap();
  boolean multiplePropertyCopies = false;
  public boolean processIncludeOntologies = true;
  private boolean optionFlag;
  //private WordNetData wordNet;
  private WordNetDictionary wordNet;
  /**
   * Constructor
   * @param ob
   */
  public OWLtoGraph(ESDOntoBrowser ob, WordNetDictionary w) {
    esdOntoBrowser = ob;
    tgPanel = esdOntoBrowser.getTGPanel();
    metadata = new OWLMetadata();
    metadata.setDefaults();
    wordNet = w;
  }

  public OWLtoGraph(ESDOntoBrowser ob) {
   esdOntoBrowser = ob;
   tgPanel = esdOntoBrowser.getTGPanel();
   metadata = new OWLMetadata();
   metadata.setDefaults();
 }

  //(top) first level function that build graph from ontology , it merely
  // calls a few second level functions
  public void buildGraphEltSet(OWLOntology ontology, Hashtable prefixMap) {
    currentOntology = ontology;
    try {
      if (processIncludeOntologies) {
        this.includeOntologies = OntologyHelper.importClosure(ontology);
      }
      else {
        this.includeOntologies = new HashSet();
        includeOntologies.add(ontology);
      }
      buildMetadata(ontology, prefixMap);

      buildOntology(this.includeOntologies, ontology);
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  private void buildMetadata(OWLOntology ontology, Hashtable prefixMap) {
    metadata = new OWLMetadata();
    String uri = "http://a.com/ontology";
    if (currentOntology != null) {
      try {
        uri = currentOntology.getLogicalURI().toString();
      }
      catch (OWLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    try {
      metadata.setBaseURI(new URI(uri));
    }
    catch (URISyntaxException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    Enumeration keys = prefixMap.keys();
    Enumeration elem = prefixMap.elements();
    Set importURI = new HashSet();
    for (Iterator ontit = this.includeOntologies.iterator();
         ontit.hasNext();
         ) {
      OWLOntology onto = (OWLOntology) ontit.next();
      try {
        importURI.add(onto.getLogicalURI().toString() + "#");
      }
      catch (OWLException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }
    }
    while (keys.hasMoreElements()) {
      String prefix = (String) keys.nextElement();
      uri = (String) elem.nextElement();
      boolean imported =
          !uri.toString().equals(metadata.getBaseURI().toString() + "#")
          && importURI.contains(uri);
      metadata.addNamespace(uri, prefix, imported);
    }
  }
  /**
   * Function to build the ontology
   * @param e being the entities present in ontology & dictionary
   * @param er1 being the first set of EntityRelationVector
   * @param er2 being the second set of EntityRelationVector
   * @param optimization whether the new ontology has been optimized
   */
  public void buildOntology(EntityVector e, EntityRelationVector er1, EntityRelationVector er2, boolean optimization ) {
    this.entities = e;
    try {
      this.visitor = new BuildGraphVisitor(esdOntoBrowser, this);
      for ( int i =0, j = entities.size(); i < j; i++ ) {
        Entity entity = entities.get(i);
        String entityName = entity.getName();
        OBObjectNode newObj = new OBObjectNode(entityName, entityName, "");
        esdOntoBrowser.renPolicy.initObject(newObj, RenderGrowl.OBJ_CLASS);
        addNode(newObj);
        nodeEntities.put(entity, newObj);
      }
      for ( int  i =0, j = er1.size(); i < j; i++ ) {
        EntityRelation er = er1.get(i);
        if (er.getEntity1() != null && er.getEntity2() != null ) {
          OBObjectNode node1 = (OBObjectNode) nodeEntities.get(er.getEntity1());
          OBObjectNode node2 = (OBObjectNode) nodeEntities.get(er.getEntity2());
          OBEdge theEdge;
          if ( optimization ) {
            theEdge = new OBEdge(node1, node2, OBEdge.SUBCLASS_OF_EDGE, Color.BLUE);
          } else {
            theEdge = new OBEdge(node1, node2, OBEdge.SUBCLASS_OF_EDGE, Color.GREEN);
          }
          esdOntoBrowser.renPolicy.resetEdge(theEdge);
          tgPanel.getCompleteEltSet().addEdge(theEdge);
          theEdge.setVisible(true);
        }
      }
      if ( er2 != null ) {
        for ( int  i =0, j = er2.size(); i < j; i++ ) {
          EntityRelation er = er2.get(i);
          if (er.getEntity1() != null && er.getEntity2() != null ) {
            OBObjectNode node1 = (OBObjectNode) nodeEntities.get(er.getEntity1());
            OBObjectNode node2 = (OBObjectNode) nodeEntities.get(er.getEntity2());
            OBEdge theEdge = new OBEdge(node1, node2, OBEdge.SUBCLASS_OF_EDGE, Color.ORANGE);
            esdOntoBrowser.renPolicy.resetEdge(theEdge);
            tgPanel.getCompleteEltSet().addEdge(theEdge);
            theEdge.setVisible(true);
          }
        }
      }
    } catch (Exception ex ) {
      JOptionPane.showMessageDialog(null,
                                    "The Ontology graph could NOT be done!\n" + ex.toString(),
                                    "Error while building the ontology",
                                    JOptionPane.ERROR_MESSAGE );
    }
  }
  public void buildOntology(Set ontologies, OWLOntology ont) {

    try {

      this.visitor = new BuildGraphVisitor(esdOntoBrowser, this);

      for (Iterator ontit = this.includeOntologies.iterator();
           ontit.hasNext();
           ) {
        OWLOntology ontology = (OWLOntology) ontit.next();
        currentOntology = ontology;
        for (Iterator it = (ontology.getClasses()).iterator();
             it.hasNext();
             ) {
          createObject(
              ontology,
              (OWLClass) it.next(),
              RenderGrowl.OBJ_CLASS);
        }

        for (Iterator it = (ontology.getIndividuals()).iterator();
             it.hasNext();
             ) {
          createObject(
              ontology,
              (OWLIndividual) it.next(),
              RenderGrowl.OBJ_INDIVIDUAL);
        }
        /*
         * for (Iterator it = (ontology.getDatatypes()).iterator();
         * it.hasNext(); ) { createObject( ((OWLDataType)
         * it.next()).getURI(), RenderGrowl.OBJ_DATATYPE); }
         */
      }

      for (Iterator ontit = this.includeOntologies.iterator();
           ontit.hasNext();
           ) {
        OWLOntology ontology = (OWLOntology) ontit.next();
        currentOntology = ontology;
        for (Iterator it = (ontology.getObjectProperties()).iterator();
             it.hasNext();
             ) {
          createObjectProperty(
              ontology,
              (OWLObjectProperty) it.next());
        }

        for (Iterator it = (ontology.getDataProperties()).iterator();
             it.hasNext();
             ) {
          createDataProperty(ontology, (OWLDataProperty) it.next());
        }

        for (Iterator it = (ontology.getClasses()).iterator();
             it.hasNext();
             ) {
          buildClassRelations(ontology, (OWLClass) it.next());
        }

        for (Iterator it = (ontology.getClasses()).iterator();
             it.hasNext();
             ) {
          buildSuperClasses(ontology, (OWLClass) it.next());
        }

        for (Iterator it = (ontology.getIndividuals()).iterator();
             it.hasNext();
             ) {
          buildIndividualRelations(
              ontology,
              (OWLIndividual) it.next());
        }

        for (Iterator it = (ontology.getClassAxioms()).iterator();
             it.hasNext();
             ) {
          buildClassAxiom( (OWLClassAxiom) it.next());
        }

        for (Iterator it = (ontology.getIndividualAxioms()).iterator();
             it.hasNext();
             ) {
          buildIndividualAxiom( (OWLIndividualAxiom) it.next());
        }

        for (Iterator it = (ontology.getClasses()).iterator();
             it.hasNext();
             ) {
          processedEntities.add(it.next());
        }
      }

      addGrounding();

      tgPanel.setGraphEltSet(1);
      for (Iterator ontit = this.includeOntologies.iterator();
           ontit.hasNext();
           ) {
        OWLOntology ontology = (OWLOntology) ontit.next();
        currentOntology = ontology;
        for (Iterator it = (ontology.getObjectProperties()).iterator();
             it.hasNext();
             ) {
          createPropertyHierarchyNodes(
              ontology,
              (OWLObjectProperty) it.next());
        }

        for (Iterator it = (ontology.getDataProperties()).iterator();
             it.hasNext();
             ) {
          createPropertyHierarchyNodes(
              ontology,
              (OWLDataProperty) it.next());
        }
      }

      for (Iterator ontit = this.includeOntologies.iterator();
           ontit.hasNext();
           ) {
        OWLOntology ontology = (OWLOntology) ontit.next();
        currentOntology = ontology;

        for (Iterator it = (ontology.getObjectProperties()).iterator();
             it.hasNext();
             ) {
          createPropertyHierarchy(
              ontology,
              (OWLObjectProperty) it.next());
        }

        for (Iterator it = (ontology.getDataProperties()).iterator();
             it.hasNext();
             ) {
          createPropertyHierarchy(
              ontology,
              (OWLDataProperty) it.next());
        }

        for (Iterator it = (ontology.getPropertyAxioms()).iterator();
             it.hasNext();
             ) {
          buildPropertyAxiom( (OWLPropertyAxiom) it.next());
        }

      }

      //delete free nodes from RBox
      GraphEltSet eltSet = tgPanel.getCompleteEltSet();
      Vector nodesToDelete = new Vector();
      Node n;
      for (Iterator i = eltSet.getNodes().iterator(); i.hasNext(); ) {
        n = (Node) i.next();
        if (! (n.getEdgeEnumeration()).hasMoreElements()) {
          nodesToDelete.add(n);
        }
      }

      for (Iterator iter = nodesToDelete.iterator(); iter.hasNext(); ) {
        esdOntoBrowser.deleteNode( (OBNode) iter.next(), false);
      }
      tgPanel.setGraphEltSet(0);
      //tgPanel.fireResetEvent();

      //now let garbage collector do its job
      currentOntology = null;
      includeOntologies = null;

    }
    catch (Exception ex) {
      ex.printStackTrace();
    }

  }

  /*
       * ground all classes with no superclasses by making them a subclass of owl:Thing
   */
  public void addGrounding() throws OWLException, TGException {
    URI thing = metadata.uriFromShortForm("owl:Thing");
    OBObjectNode thingNode =
        (OBObjectNode) tgPanel.getCompleteEltSet().findNode(
        thing.toString());
    if (thingNode == null) { // add an owl:Thing node if none exists
      thingNode = createObject(thing, RenderGrowl.OBJ_CLASS);
      thingNode.setInferred(true); // prevent Thing from being rendered
    }
    GraphUtil.setThingNode(thingNode);
    Set owlObjects = esdOntoBrowser.getObjectNodes(RenderGrowl.OBJ_CLASS);
    for (Iterator i = owlObjects.iterator(); i.hasNext(); ) { // iterate through all named classes
      OBObjectNode node = (OBObjectNode) i.next();
      if (!node.equals(thingNode)) {
        Vector outputs = node.getOutputs();
        if (!hasSuperclass(node)) { // any class with no superclasses is linked to Thing
          createEdge(node, thingNode, OBEdge.SUBCLASS_OF_EDGE);
        }
      }
    }
  }

  private boolean hasSuperclass(OBObjectNode node) {
    return GraphUtil.getSuperClasses(node).size() > 0;
  }

  //secondlevel functions to build graph from ontology

  public void createObject(
      OWLOntology ontology,
      OWLNamedObject owlObj,
      int type) throws OWLException, TGException {
    if (processedEntities.contains(owlObj)) {
      return;
    }
    URI uri = owlObj.getURI();
    if (uri == null) {
      return;
    }
    OBObjectNode newObj =
        (OBObjectNode) tgPanel.getCompleteEltSet().findNode(uri.toString());
    if (newObj != null) {
      return;
    }

    newObj = new OBObjectNode(uri.toString(), metadata.shortForm(uri), "");

    /*String rdfsLabel = getRDFSLabel(owlObj, ontology);
         if (rdfsLabel != null) {
      newObj.setNodeLabel(metadata.getNamespacePrefix(uri) + rdfsLabel);
      /* metadata.shortForm(uri)
              }*/

    esdOntoBrowser.renPolicy.initObject(newObj, type);
    //newObj.setLabel(shortForm(uri));

    newObj.setURI(uri);
    newObj.setNamespace(getMetadata().getPrefixOfFullURI(uri));
    String hint = getCommment(owlObj, ontology);
    ;
    /* for (Iterator it = owlObj.getAnnotations(ontology).iterator();
     it.hasNext();
     ) {
     OWLAnnotationInstance oai = (OWLAnnotationInstance) it.next();
     Object content = oai.getContent();
     if (content instanceof OWLDataValue) {
      if (((OWLDataValue) content).getURI() != null
       && ((OWLDataValue) content)
        .getURI()
        .getFragment()
        .equalsIgnoreCase(
        "string"))
       hint = hint + ((OWLDataValue) content).getValue();
     } else {
      hint = hint + content;
     }
       }  */
    newObj.setHint(hint);
    addNode(newObj);
  }

  public OBObjectNode createObject(URI uri, int type) throws OWLException,
      TGException {
    if (uri == null) {
      return null;
    }
    OBObjectNode newObj =
        (OBObjectNode) tgPanel.getCompleteEltSet().findNode(uri.toString());
    if (newObj != null) {
      return newObj;
    }
    newObj = new OBObjectNode(uri.toString(), uri.getFragment()
                              /* metadata.shortForm(uri) */
                              , "");
    esdOntoBrowser.renPolicy.initObject(newObj, type);
    //newObj.setLabel(shortForm(uri));
    newObj.setURI(uri);
    newObj.setNamespace(getMetadata().getPrefixOfFullURI(uri));
    addNode(newObj);
    return newObj;

  }

  //?????
  private void buildClassRelations(OWLOntology ontology, OWLClass clazz) throws
      OWLException, TGException {
    if (processedEntities.contains(clazz)) {
      return;
    }
    visitor.setMode(BuildGraphVisitor.SAME_AS);
    OBObjectNode classNode = visitor.findNode(clazz);
    for (Iterator it =
         clazz.getEquivalentClasses(this.includeOntologies).iterator();
         it.hasNext();
         ) {
      OWLDescription eqclass = (OWLDescription) it.next();
      visitor.reset();
      visitor.setMode(BuildGraphVisitor.OPERATOR);
      //visitor.setFromNode(classNode);
      eqclass.accept(visitor);
      //if (visitor.getBaseNode() != null)
      createEdge(
          classNode,
          visitor.getBaseNode(),
          OBEdge.EQUIVALENT_EDGE);

      //this OWLDescription function will merely call
      // visitor.visit(this), in our case this==superclass
      //equals may be any implementation of OWLDescription interface, see
      // BuildSupereclassVisitor for details
    }

    for (Iterator it =
         (clazz.getEnumerations(this.includeOntologies)).iterator();
         it.hasNext();
         ) {

      OWLEnumeration en = (OWLEnumeration) it.next();
      visitor.reset();
      visitor.setMode(BuildGraphVisitor.OPERATOR);
      //visitor.setFromNode(classNode);
      en.accept(visitor);
      //if (visitor.getBaseNode() != null)
      createEdge(
          classNode,
          visitor.getBaseNode(),
          OBEdge.EQUIVALENT_EDGE);
    }
  }

  //uses visitor pattern. All complexity is hiden in BuildSupereclassVisitor
  // object scvisitor
  private void buildSuperClasses(OWLOntology ontology, OWLClass clazz) throws
      OWLException, TGException {
    //visitor.setMode(BuildGraphVisitor.SUPERCLASS);
    if (processedEntities.contains(clazz)) {
      return;
    }
    OBObjectNode classNode = visitor.findNode(clazz);
    if (classNode != null) {
      for (Iterator it =
           clazz.getSuperClasses(this.includeOntologies).iterator();
           it.hasNext();
           ) {
        OWLDescription superclass = (OWLDescription) it.next();
        visitor.reset();
        visitor.setMode(BuildGraphVisitor.OPERATOR);
        //visitor.setFromNode(classNode);
        superclass.accept(visitor);
        createEdge(
            classNode,
            visitor.getBaseNode(),
            OBEdge.SUBCLASS_OF_EDGE);
        //this OWLDescription function will merely call
        // visitor.visit(this), in our case this==superclass
        //equals may be any implementation of OWLDescription interface, see
        // BuildSupereclassVisitor for details
      }
    }
  }

  private void buildIndividualRelations(
      OWLOntology ontology,
      OWLIndividual ind) throws OWLException, TGException {

    if (ind.isAnonymous()) {
      Map m = ind.getIncomingObjectPropertyValues(ontology);
      if (!m.isEmpty()) {
        return;
      }
    }

    if (ind.getTypes(ontology).isEmpty()
        && ind.getObjectPropertyValues(ontology).keySet().isEmpty()
        && ind.getDataPropertyValues(ontology).keySet().isEmpty()) {
      return;
    }
    else {
      //visitor.setMode(BuildGraphVisitor.TYPE);
      OBObjectNode indNode = visitor.findNode(ind);
      if (indNode == null) {
        return;
      }
      for (Iterator it = ind.getTypes(ontology).iterator();
           it.hasNext();
           ) {
        OWLDescription type = (OWLDescription) it.next();
        visitor.setMode(BuildGraphVisitor.INSTANCE);
        visitor.reset();
        visitor.setMode(BuildGraphVisitor.OPERATOR);
        //visitor.setFromNode(indNode);
        type.accept(visitor);
        createEdge(
            indNode,
            visitor.getBaseNode(),
            OBEdge.INSTANCE_OF_EDGE);

      }
      Map propertyValues = ind.getObjectPropertyValues(ontology);
      for (Iterator it = propertyValues.keySet().iterator();
           it.hasNext();
           ) {
        OWLObjectProperty prop = (OWLObjectProperty) it.next();
        Set vals = (Set) propertyValues.get(prop);
        buildObjectPropertyValue(prop, indNode, vals, ontology);

      }
      Map dataValues = ind.getDataPropertyValues(ontology);

      for (Iterator it = dataValues.keySet().iterator(); it.hasNext(); ) {

        OWLDataProperty prop = (OWLDataProperty) it.next();
        Set vals = (Set) dataValues.get(prop);
        buildDataPropertyValue(prop, indNode, vals, ontology);

      }

    }

  }

  private void createDataProperty(OWLOntology ontology, OWLDataProperty prop) throws
      OWLException, TGException {
    URI uri = prop.getURI();
    OBRelationNode relNode = null;
    if (processedEntities.contains(prop)) {
      return;
    }
    if (uri == null) {
      return;
    }
    multiplePropertyCopies = false;
    //do ranges
    Set ranges = prop.getRanges(this.includeOntologies);
    Set domains = prop.getDomains(this.includeOntologies);

    OBNode rangeNode = null;
    Iterator it = ranges.iterator();
    if (ranges.size() > 1) {
      String OPID = visitor.createOperatorID(ranges, "and");
      rangeNode =
          visitor.createOperator(
          ranges,
          RenderGrowl.OBJ_INTERSECTION,
          OPID);
      visitor.putRangeID(uri.toString(), rangeNode.getID());
    }
    else if (it.hasNext()) {
      OWLDataRange range = (OWLDataRange) it.next();
      visitor.reset();
      visitor.setMode(BuildGraphVisitor.OPERATOR);
      range.accept(visitor);
      rangeNode = visitor.getBaseNode();
      visitor.putRangeID(uri.toString(), rangeNode.getID());
    }

    //do domains and the rest

    OBNode domNode = null;
    it = domains.iterator();
    if (domains.size() > 1) {
      String OPID = visitor.createOperatorID(domains, "and");
      domNode =
          visitor.createOperator(
          domains,
          RenderGrowl.OBJ_INTERSECTION,
          OPID);

    }
    else if (it.hasNext()) {
      OWLDescription dom = (OWLDescription) it.next();
      //if (!(dom instanceof OWLOr)) {
      visitor.reset();
      visitor.setMode(BuildGraphVisitor.OPERATOR);
      dom.accept(visitor);
      domNode = visitor.getBaseNode();
    }

    relNode =
        buildRelationNode(
        uri,
        domNode,
        rangeNode,
        RenderGrowl.REL_DATA_PROPERTY);
    setDataPropertyParameters(prop, relNode);
    /*String rdfsLabel = getRDFSLabel(prop, ontology);
         if (rdfsLabel != null) {
      relNode.setNodeLabel(metadata.getNamespacePrefix(uri) + rdfsLabel);
         }*/
    relNode.setHint(getCommment(prop, ontology));
    processedEntities.add(prop);
  }

  private void createObjectProperty(OWLOntology ontology,
                                    OWLObjectProperty prop) throws OWLException,
      TGException {

    if (processedEntities.contains(prop)) {
      return;
    }
    URI uri = prop.getURI();
    OBRelationNode relNode = null;
    if (uri == null) {
      return;
    }
    multiplePropertyCopies = false;
    //do ranges
    Set ranges = prop.getRanges(this.includeOntologies);
    Set domains = prop.getDomains(this.includeOntologies);

    OBNode rangeNode = null;
    Iterator it = ranges.iterator();
    if (ranges.size() > 1) {
      String OPID = visitor.createOperatorID(domains, "and");
      rangeNode =
          visitor.createOperator(
          ranges,
          RenderGrowl.OBJ_INTERSECTION,
          OPID);
      visitor.putRangeID(uri.toString(), rangeNode.getID());
    }
    else if (it.hasNext()) {
      OWLDescription range = (OWLDescription) it.next();
      visitor.reset();
      visitor.setMode(BuildGraphVisitor.OPERATOR);
      range.accept(visitor);
      rangeNode = visitor.getBaseNode();
      visitor.putRangeID(uri.toString(), rangeNode.getID());
    }

    //do domains and the rest
    OBNode domNode = null;
    it = domains.iterator();
    if (domains.size() > 1) {
      String OPID = visitor.createOperatorID(domains, "and");
      domNode =
          visitor.createOperator(
          domains,
          RenderGrowl.OBJ_INTERSECTION,
          OPID);

    }
    else if (it.hasNext()) {
      OWLDescription dom = (OWLDescription) it.next();
      //if (!(dom instanceof OWLOr)) {
      visitor.reset();
      visitor.setMode(BuildGraphVisitor.OPERATOR);
      dom.accept(visitor);
      domNode = visitor.getBaseNode();

      /*} else {
       Set ops = ((OWLOr) dom).getOperands();
       multiplePropertyCopies = true;
       for (Iterator it1 = ops.iterator(); it1.hasNext();) {
        OWLDescription opDescr = (OWLDescription) it1.next();
        visitor.reset();
        visitor.setMode(BuildGraphVisitor.OPERATOR);
        opDescr.accept(visitor);
        OBObjectNode opNode = visitor.getObject();
        relNode =
         buildRelationNode(
          uri,
          opNode,
          rangeNode,
          RenderGrowl.REL_OBJECT_PROPERTY);
        setObjPropertyParameters(prop, relNode);
       }
       multiplePropertyCopies = false;
          }*/
    }

    relNode =
        buildRelationNode(
        uri,
        domNode,
        rangeNode,
        RenderGrowl.REL_OBJECT_PROPERTY);
    setObjPropertyParameters(prop, relNode);
    /*String rdfsLabel = getRDFSLabel(prop, ontology);
         if (rdfsLabel != null) {
      relNode.setNodeLabel(metadata.getNamespacePrefix(uri) + rdfsLabel);
         }*/
    relNode.setHint(getCommment(prop, ontology));
    processedEntities.add(prop);

  }

  public void createPropertyHierarchyNodes(
      OWLOntology ontology,
      OWLProperty prop) {

    URI uri;
    try {
      uri = prop.getURI();
      if (uri == null) {
        return;
      }
      if (uri.toString() == null) {
        return;
      }
      OBRelationNode newRNode = visitor.findRelationNode(uri.toString());
      if (newRNode != null) {
        return;
      }

      newRNode = new OBRelationNode(uri.toString(),
                                    //+ String.valueOf(BuildGraphVisitor.anonimousCounter),
                                    metadata.shortForm(uri), "");

      /*String rdfsLabel = getRDFSLabel(prop, ontology);
             if (rdfsLabel != null) {
        newRNode.setNodeLabel(metadata.getNamespacePrefix(uri) + rdfsLabel);
             }*/
      newRNode.setURI(uri);
      newRNode.setNamespace(getMetadata().getPrefixOfFullURI(uri));
      if (prop instanceof OWLObjectProperty) {
        esdOntoBrowser.renPolicy.initRelation(
            newRNode,
            RenderGrowl.REL_OBJECT_PROPERTY);
        setObjPropertyParameters( (OWLObjectProperty) prop, newRNode);
      }
      else {
        esdOntoBrowser.renPolicy.initRelation(
            newRNode,
            RenderGrowl.REL_DATA_PROPERTY);
        setDataPropertyParameters( (OWLDataProperty) prop, newRNode);
      }

      newRNode.resetCategory(esdOntoBrowser.renPolicy);
      addNode(newRNode);
    }
    catch (OWLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

  }

  public void createPropertyHierarchy(
      OWLOntology ontology,
      OWLProperty prop) {

    try {

      OBRelationNode from =
          visitor.findRelationNode(prop.getURI().toString());

      Set superProp = prop.getSuperProperties(includeOntologies);
      for (Iterator iter = superProp.iterator(); iter.hasNext(); ) {
        OWLProperty sp = (OWLProperty) iter.next();
        OBRelationNode to =
            visitor.findRelationNode(sp.getURI().toString());
        //buildRelationNode(null, from, to, RenderGrowl.REL_SUBCLASS);
        createEdge(from, to, OBEdge.SUBCLASS_OF_EDGE);
      }

      if (prop instanceof OWLObjectProperty) {

        Set invProp =
            ( (OWLObjectProperty) prop).getInverses(includeOntologies);
        for (Iterator iter = invProp.iterator(); iter.hasNext(); ) {
          OWLProperty ip = (OWLObjectProperty) iter.next();
          OBRelationNode to =
              visitor.findRelationNode(ip.getURI().toString());
          buildRelationNode(
              null,
              from,
              to,
              RenderGrowl.REL_INVERSE_OF);
        }
      }
    }
    catch (OWLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    catch (TGException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

  }

  /*
   * public void createDataPropertyHierarchy( OWLOntology ontology,
   * OWLDataProperty prop) { }
   */
  public OBRelationNode buildRelationNode(
      URI uri,
      OBNode domNode,
      OBNode rangeNode,
      int type) throws OWLException, TGException {
    BuildGraphVisitor.anonimousCounter++;
    String strURI = "";
    if (uri != null) {
      strURI = uri.toString();
    }
    String ID = strURI //+ domNode.getLabel() + rangeNode.getLabel();
        + String.valueOf(type) +
        String.valueOf(BuildGraphVisitor.anonimousCounter);
    if (multiplePropertyCopies) {
      ID = ID + domNode.getLabel() + rangeNode.getLabel();
    }
    OBRelationNode newRNode = new OBRelationNode(ID, "", "");
    esdOntoBrowser.renPolicy.initRelation(newRNode);
    if (uri != null) {
      newRNode.setLabel(metadata.shortForm(uri));
      newRNode.setURI(uri);
      newRNode.setNamespace(getMetadata().getPrefixOfFullURI(uri));
    }
    addNode(newRNode);
    if (domNode != null) {
      createEdge(domNode, newRNode, OBEdge.START_EDGE);
    }
    if (rangeNode != null) {
      createEdge(newRNode, rangeNode, OBEdge.END_EDGE);
    }
    newRNode.setRelationSubCategory(type);
    newRNode.resetCategory(esdOntoBrowser.renPolicy);
    return newRNode;
  }

  private void buildClassAxiom(OWLClassAxiom classAxiom) throws OWLException {
    visitor.reset();
    classAxiom.accept(visitor);
  }

  private void buildPropertyAxiom(OWLPropertyAxiom propAxiom) throws
      OWLException {
    visitor.reset();
    propAxiom.accept(visitor);
  }

  private void buildIndividualAxiom(OWLIndividualAxiom indAxiom) throws
      OWLException {
    visitor.reset();
    indAxiom.accept(visitor);
  }

  //third level functions to build graph from ontology

  private void buildObjectPropertyValue(
      OWLObjectProperty prop,
      OBNode fromNode,
      Set toObjects,
      OWLOntology ontology) throws OWLException, TGException {
    URI uri = prop.getURI();
    if (uri == null) {
      return;
    }

    if (fromNode == null) {
      return;
    }
    OBRelationNode newRNode =
        new OBRelationNode(fromNode.getID() + uri.toString(), "", "");
    esdOntoBrowser.renPolicy.initRelation(newRNode);
    newRNode.setLabel(metadata.shortForm(uri));
    newRNode.setURI(uri);
    newRNode.setNamespace(getMetadata().getPrefixOfFullURI(uri));
    setObjPropertyParameters(prop, newRNode);
    //add them
    addNode(newRNode);
    //add start edge
    createEdge(fromNode, newRNode, OBEdge.START_EDGE);
    for (Iterator it = toObjects.iterator(); it.hasNext(); ) {
      OWLIndividual toObj = (OWLIndividual) it.next();

      OBObjectNode toNode = visitor.findNode(toObj);
      if (toNode != null) {
        createEdge(newRNode, toNode, OBEdge.END_EDGE);

      }
    }
    newRNode.setRelationSubCategory(RenderGrowl.REL_OBJECT_PROPERTY_VALUE);
    newRNode.resetCategory(esdOntoBrowser.renPolicy);
    /*String label = getRDFSLabel(prop, ontology);
         if (label != null) {
      newRNode.setLabel(metadata.getPrefixOfFullURI(uri) + ":" + label);
         }*/
    newRNode.setHint(getCommment(prop, ontology));
  }

  private void buildDataPropertyValue(
      OWLDataProperty prop,
      OBNode fromNode,
      Set toObjects,
      OWLOntology ontology) throws OWLException, TGException {
    URI uri = prop.getURI();

    OBRelationNode newRNode =
        new OBRelationNode(fromNode.getID() + uri.toString(), "", "");
    esdOntoBrowser.renPolicy.initRelation(newRNode);
    newRNode.setLabel(metadata.shortForm(uri));
    newRNode.setURI(uri);
    newRNode.setNamespace(getMetadata().getPrefixOfFullURI(uri));
    setDataPropertyParameters(prop, newRNode);
    //add them
    addNode(newRNode);
    //add start edge
    createEdge(fromNode, newRNode, OBEdge.START_EDGE);
    for (Iterator it = toObjects.iterator(); it.hasNext(); ) {
      OWLDataValue toObj = (OWLDataValue) it.next();
      visitor.reset();
      visitor.setMode(BuildGraphVisitor.OPERATOR);
      toObj.accept(visitor);
      OBNode toNode = visitor.getBaseNode();
      createEdge(newRNode, toNode, OBEdge.END_EDGE);

    }

    newRNode.setRelationSubCategory(RenderGrowl.REL_DATA_PROPERTY_VALUE);
    newRNode.resetCategory(esdOntoBrowser.renPolicy);
    /*String label = getRDFSLabel(prop, ontology);
         if (label != null) {
      newRNode.setLabel(metadata.getPrefixOfFullURI(uri) + ":" + label);
         }*/
    newRNode.setHint(getCommment(prop, ontology));
  }

  protected void addNode(OBNode node) {
    try {
      tgPanel.getCompleteEltSet().addNode(node);
      node.setLocation(
          new Point(
          (int) (500 * Math.random()),
          (int) (500 * Math.random())));
      node.setVisible(true);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  public OBEdge createEdge(OBNode fromNode, OBNode toNode, int type) {
    OBEdge theEdge = new OBEdge(fromNode, toNode, type);
    esdOntoBrowser.renPolicy.resetEdge(theEdge);
    tgPanel.getCompleteEltSet().addEdge(theEdge);
    theEdge.setVisible(true);
    return theEdge;
  }

  public String getBaseURI() {
    return metadata.getBaseURI().toString();
  }

  public void setBaseURI(String s) throws URISyntaxException {
    metadata.setBaseURI(new URI(s));
  }

  /**
   * private void generateShortNames() { // Generates a list of namespaces.
   * shortNames = new ArrayList(); known = new HashMap();
   * known.put(OWLVocabularyAdapter.OWL, "owl");
   * known.put(RDFVocabularyAdapter.RDF, "rdf");
   * known.put(RDFSVocabularyAdapter.RDFS, "rdfs");
   * known.put(XMLSchemaSimpleDatatypeVocabulary.XS, "xsd");
   *
   * for (Iterator it = allURIs.iterator(); it.hasNext();) { try { URI uri =
   * (URI) it.next(); if (uri.getFragment() != null) { String ssp = new URI(
   * uri.getScheme(), uri.getSchemeSpecificPart(), null) .toString(); // Trim
   * off the fragment bit if necessary if (!ssp.endsWith("#")) { ssp = ssp +
   * "#"; } if (!known.keySet().contains(ssp) && !shortNames.contains(ssp)) {
   * shortNames.add(ssp); } } } catch (URISyntaxException ex) { } } }
   */
  public void setObjPropertyParameters(
      OWLObjectProperty prop,
      OBRelationNode relNode) {
    try {
      relNode.isTransitive = prop.isTransitive(includeOntologies);
      relNode.isFunctional = prop.isFunctional(includeOntologies);
      relNode.isOneToOne = prop.isOneToOne(includeOntologies);
      relNode.isSimmetric = prop.isSymmetric(includeOntologies);
      relNode.isInverseFunctional =
          prop.isInverseFunctional(includeOntologies);
    }
    catch (OWLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  public void setDataPropertyParameters(
      OWLDataProperty prop,
      OBRelationNode relNode) {
    try {
      relNode.isFunctional = prop.isFunctional(includeOntologies);
    }
    catch (OWLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  public OWLOntology getOntology() {
    return currentOntology;
  }

  /**
   *
   * @return includeOntologies
   */
  public Set getIncludeOntologies() {
    return includeOntologies;
  }

  /**
   * Method getMetadata
   * @return OWLMetadata
   */
  public OWLMetadata getMetadata() {
    return metadata;
  }

  public static String getCommment(OWLNamedObject oo, OWLOntology ontology) {
    OWLAnnotationProperty rdfComment = null;

    try {
      rdfComment =
          ontology.getOWLDataFactory().getOWLAnnotationProperty(
          new URI(OWLVocabularyAdapter.INSTANCE.getComment()));
      Set annos = oo.getAnnotations(ontology);
      for (Iterator annoIt = annos.iterator(); annoIt.hasNext(); ) {

        OWLAnnotationInstance annInst =
            (OWLAnnotationInstance) annoIt.next();
        if (annInst.getProperty().equals(rdfComment)) {
          /* We've got an annotation using the right property */
          if (annInst.getContent()instanceof OWLDataValue) {
            OWLDataValue odv = (OWLDataValue) annInst.getContent();
            return (String) odv.getValue();

          }
        }
      }
    }
    catch (OWLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    catch (URISyntaxException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return "";
  }
}
